package com.doom.a3rdlibdemo.ui.main;

import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

public class LiveDataBus<T> extends MutableLiveData<T> {

    private static final String TAG = LiveDataBus.class.getSimpleName();
    private Object mVersionObject = null;

    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        try {
            hookFirst(observer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.observe(owner, observer);
        try {
            hook(observer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private <T> void hookFirst(Observer<? super T> observer) throws Exception {
        Class<LiveData> liveDataClass = LiveData.class;
        Field mObserversField = liveDataClass.getDeclaredField("mObservers");
        Field mVersion = liveDataClass.getDeclaredField("mVersion");
        mVersion.setAccessible(true);
        mVersionObject = mVersion.get(this);
        mVersion.set(this, Integer.valueOf(-1));
    }

    private <T> void hook(Observer<? super T> observer) throws Exception {
        Class<LiveData> liveDataClass = LiveData.class;
        Field mObserversField = liveDataClass.getDeclaredField("mObservers");
        mObserversField.setAccessible(true);
        //获取mObservers的值，也就是SafeIterableMap对象
        Object objectObservers = mObserversField.get(this);
        //获取SafeIterableMap 的class对象
        Class<?> classObjectObservers = objectObservers.getClass();
        //获取SafeIterableMap的get方法
        Method safeIterableMapGetMethod = classObjectObservers.getDeclaredMethod("get", Object.class);
        //因为原本的权限是protected
        safeIterableMapGetMethod.setAccessible(true);
        //执行get方法，并且获取返回值是map.entry的
        Object objectWrapperEntry = safeIterableMapGetMethod.invoke(objectObservers, observer);
        Object objectWrapper = null;
        if (objectWrapperEntry instanceof Map.Entry) {
            //getValue方法返回的值其实是ObserverWrapper的子类
            objectWrapper = ((Map.Entry) (objectWrapperEntry)).getValue();
        }
        if (objectWrapper == null) {
            throw new NullPointerException("Wrapper can not be bull!");
        }
        //获取objectWrapper的class的父类class
        Class<?> superclass = objectWrapper.getClass().getSuperclass();
        //mLastVersion属性是在objectWrapper中的
        Field mLastVersion = superclass.getDeclaredField("mLastVersion");
        mLastVersion.setAccessible(true);
        //获取LiveData的mVersion属性
        Field mVersion = liveDataClass.getDeclaredField("mVersion");
        mVersion.setAccessible(true);
        //获取mVersion的值
        Object mVersionValue = mVersionObject;//mVersion.get(this);
        mVersion.set(this, mVersionObject);
        //设置mLastVersion的值
        mLastVersion.set(objectWrapper, mVersionValue);
    }
}
